<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>作业讲解</title>
</head>

<body>
    <script>
        /*
    分别用原始模式，工厂模式，构造函数模式创建一个盒子对象。要求如下
    (1)对象有以下属性：宽度(不带单的数字类型，默认单位为cm)，高度(同宽度)，背景颜色，位置。长度单位可选mm（毫米）,cm(厘米)，dm(分米),m(米)。
    (2)可对盒子对象的宽度和高度属性设置带长度单位的字符串，对象会自动转换成cm。如:设置box.width='1.2m'，获取box.width返回不带单位的数字120，也可直接设置数字。提示Object.defineproperties，查询文档或者上课案例。
    (3)有方法getSize()获取盒子大小。返回数字，默认平方厘米。
    */
        let box = {
            _width: 0,
            _height: 0,
            color: 'red',
            getSize: function () {
                return this.width * this.height
            }
        }
        Object.defineProperties(box, {

            '_width': {
                enumerable: false
            },
            '_height': {
                enumerable: false
            },
            'width': {
                set: function (value) {
                    this._width = transform(value)
                },
                get: function () {
                    return this._width
                }
            },
            'height': {
                set: function (value) {
                    this._height = transform(value)
                },
                get: function () {
                    return this._height
                }
            },

        })
        //'102cm' -> 102 
        function transform(value) {
            if (!isNaN(value)) {
                return value
            }
            let num = parseFloat(value)
            let unit = value.replace(num, '')
            switch (true) {
                case unit == 'm':
                    num *= 100;
                    break;
                case unit == 'dm':
                    num *= 10;
                    break;
                case unit == 'cm':
                    break;
                case unit == 'mm':
                    num /= 10
            }
            return num
        }
        //工厂模式
        function createBox(width, height, color) {
            let box = {}
            Object.defineProperties(box, {

                '_width': {
                    enumerable: false,
                    writable: true,
                    value: 0
                },
                '_height': {
                    enumerable: false,
                    writable: true,
                    value: 0
                },
                'width': {
                    set: function (value) {
                        this._width = transform(value)
                    },
                    get: function () {
                        return this._width
                    }
                },
                'height': {
                    set: function (value) {
                        this._height = transform(value)
                    },
                    get: function () {
                        return this._height
                    }
                },
            })
            box.width = width
            box.height = height
            box.getSize = function () {
                return this._width * this._height
            }
            return box
        }

        let box1 = createBox('12.5mm', '45.2dm', 'green')
        //构造函数方式
        function Box(width, height, color) {
            this._width = 0
            this._height = 0
            Object.defineProperties(this, {
                '_width': {
                    enumerable: false,
                    // writable: true,
                    value: 0
                },
                '_height': {
                    enumerable: false,
                    // writable: true,
                    value: 0
                },
                'width': {
                    set: function (value) {
                        this._width = transform(value)
                    },
                    get: function () {
                        return this._width
                    }
                },
                'height': {
                    set: function (value) {
                        this._height = transform(value)
                    },
                    get: function () {
                        return this._height
                    }
                },
            })

            this.width = width
            this.height = height
            this.getSize = function () {
                return this._width * this._height
            }
        }


        let box2 = new Box('121.45mm', '45dm', 'red')

        /*
        给所有字符串添加一个方法replaceAll方法的，实现一下功能。'abcaba'.replaceAll('a','x')，替换所有的字母a为z，返回结果为'xbcxbx'。
        */


        // String.prototype.replaceAll = function (searchValue, replaceValue) {
        //     let s = this
        //     while (s.includes(searchValue)) {
        //         s = s.replace(searchValue, replaceValue)
        //     }
        //     return s
        // }

        String.prototype.replaceAll = function (searchValue, replaceValue) {
            let s = ''
            let step = searchValue.length
            console.log(step)
            for (let i = 0; i < this.length; i++) {
                if (this.slice(i, i + step) == searchValue) {
                    s += replaceValue
                    i += step - 1
                } else {
                    s += this[i]
                }
            }
            return s

        }
        Object.defineProperty(String.prototype, 'replaceAll', {
            enumerable: false
        })

        /*给数组添加一个方法max，min可以返回数组的最大值和最小值，且不改变原数组。*/
        Array.prototype.max = function () {
            //数组的浅拷贝
            let arr = this.slice()
            arr.sort(function (a, b) {
                return a - b
            })
            return arr[arr.length - 1]
        }
        Array.prototype.min = function () {
            //数组的浅拷贝
            let arr = this.slice()
            arr.sort(function (a, b) {
                return a - b
            })
            return arr[0]
        }

        let arr1 = [67, 45, 98, 100, 36]

        /*
        给数组添加一个add方法，该方法接受一个参数为另一个数组，返回两个数组对应位置相加的和的数组。对于较短数组后的位置，可以当作0处理。如[1,2,3].add([2,3]) 返回[3,5,3]。
        */
        Array.prototype.add = function (otherArray) {
            let res = []
            let max = Math.max(this.length, otherArray.length)
            for (let i = 0; i < max; i++) {
                let n1 = isNaN(this[i]) ? 0 : this[i]
                let n2 = isNaN(otherArray[i]) ? 0 : otherArray[i]
                res.push(n1+n2)
            }
            return res
        }
        let a1 = [1,2,3,4]
        let a2 = [6,7,8]
    </script>
</body>

</html>